package com.example.demo.batch_handle;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.*;

/**
 *  一些使用for循环的分批处理的思路
 *
 *  如 各有100w数据，要去比对直接的差值
 * */
public class For_test {

    public static final int POOLSIZE = 8;
    public static final int DATASIZE = 1000000;

    public static void main(String[] args) throws InterruptedException, ExecutionException {

        ExecutorService executorService = Executors.newFixedThreadPool(POOLSIZE);
        ExecutorCompletionService<Boolean> executorCompletionService = new ExecutorCompletionService<>(executorService);

        //数据1  1000000条
        Set<String> set1 = creatDataSet(DATASIZE);
        //todo 利用空间换时间思想，不要在循环里面比对的时候换成数组
        String[] array = set1.toArray(new String[0]);
        //数据2  1000000条
        Set<String> set2 = creatDataSet(DATASIZE);

        // 记录开始时间
        long startTime = System.currentTimeMillis();


        //todo 这里的思想是将一个大的值分成几批，每批都去同时进行

        //todo 将任务分成了5批。没批的i是这一批的起始值
        for (int i = 0; i < DATASIZE; i += DATASIZE/POOLSIZE) {
            System.out.println(i); //0  2000   4000  6000 8000
            final int start = i;
            //这里可以开启线程池去做
            executorCompletionService.submit(()->{
                //todo 如果要分批处理只需要  当前这一批的值加上每批的大小
                for (int j = 0; j < start+DATASIZE/POOLSIZE; j ++) {
                    if (!set2.contains(array[j])) {
                        return false;
                    }
                }
                return true;
            });

        }

        //等待所有任务完成
        int finishedTasks = 0;
        boolean isIdentical = true;
        while (finishedTasks < POOLSIZE) {

            Future<Boolean> take = executorCompletionService.take();
            if (!take.get()) {
                 isIdentical = false;
                //有线程检测到不一样的数据
                break;
            }
            finishedTasks++;

        }
        // 记录结束时间
        long endTime = System.currentTimeMillis();
        System.out.println("是否相同: " + isIdentical);
        System.out.println("耗时: " + (endTime - startTime) + "毫秒");




    }


    public static Set<String> creatDataSet(int size){
        Set<String> objects = new HashSet<>(DATASIZE);
        for (int i = 0; i < size; i++) {
            objects.add("items:"+String.valueOf(i));
        }
        return objects;
    }

}
